/**
 * @example 验证电子邮箱格式
 * @param {String} value 须要验证的数值
 * @returns {Boolean} 是true, 否false
 */
export const email = value => {
  return /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/.test(value)
}

/**
 * @example 验证手机格式
 * @param {String} value 须要验证的数值
 * @returns {Boolean} 是true, 否false
 */
export const mobile = value => {
  return /^1[23456789]\d{9}$/.test(value)
}

/**
 * @example 验证URL格式
 * @param {String} value 须要验证的数值
 * @returns {Boolean} 是true, 否false
 */
export const url = value => {
  return /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i
    .test(value)
}

/**
 * @example 验证日期格式
 * @param {String | date} value 须要验证的数值
 * @returns {Boolean} 是true, 否false
 */
export const date = value => {
  return !/Invalid|NaN/.test(new Date(value).toString())
}

/**
 * @example 验证ISO类型的日期格式
 * @param {String} value 须要验证的数值
 * @returns {Boolean} 是true, 否false
 */
export const dateISO = value => {
  return /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value)
}

/**
 * @example 验证十进制数字
 * @param {Number} value 须要验证的数值
 * @returns {Boolean} 是true, 否false
 */
export const number = value => {
  return /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value)
}

/**
 * @example 验证整数
 * @param {Number} value 须要验证的数值
 * @returns {Boolean} 是true, 否false
 */
export const digits = value => {
  return /^\d+$/.test(value)
}

/**
 * @example 验证身份证号码
 * @param {String} value 须要验证的数值
 * @returns {Boolean} 是true, 否false
 */
export const idCard = value => {
  return /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)
}

/**
 * @example 验证是否车牌号
 * @param {String} value 须要验证的数值
 * @returns {Boolean} 是true, 否false
 */
export const carNo = value => {
  // 新能源车牌
  const xreg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/
  // 旧车牌
  const creg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/
  if (value.length === 7) {
    return creg.test(value)
  } else if (value.length === 8) {
    return xreg.test(value)
  } else {
    return false
  }
}

/**
 * @example 验证金额,可以是正数和负数 只允许2位小数,
 * @param {String | Number} value 须要验证的数值
 * @returns {Boolean} 是true, 否false
 */
export const amount = value => {
  return /(^([-]?)[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^([-]?)(0){1}$)|(^([-]?)[0-9]\.[0-9]([0-9])?$)/.test(value)
  // return /(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/.test(value)
  // 下面为不能为负数
  // return /^[1-9]\d*(,\d{3})*(\.\d{1,2})?$|^0.\d{1,2}$/.test(value)
}

/**
 * @example 验证是否中文
 * @param {String} value 须要验证的数值
 * @returns {Boolean} 是true, 否false
 */
export const chinese = value => {
  const reg = /^[\u4e00-\u9fa5]+$/gi
  return reg.test(value)
}

/**
 * @example 验证只能输入字母
 * @param {String} value 须要验证的数值
 * @returns {Boolean} 是true, 否false
 */
export const letter = value => {
  return /^[a-zA-Z]*$/.test(value)
}

/**
 * @example  只能是字母或者数字,英文或者数字
 * @param {String} value 须要验证的数值
 * @returns {Boolean} 是true, 否false
 */
export const enOrNum = value => {
  const reg = /^[0-9a-zA-Z]*$/g
  return reg.test(value)
}

/**
 * @example  验证是否包含某个值,此方法只针对字串类型
 * @param {String} value 须要验证的数值
 * @param {String} param 包含某个值
 * @returns {Boolean} 是true, 否false
 */
export const contains = (value, param) => {
  return value.indexOf(param) >= 0
}

/**
 * @example  验证验证一个值范围,包括等于
 * @param {Number} value 须要验证的数值
 * @param {Array} param [min最小数, max最大数]
 * @returns {Boolean} 是true, 否false
 */
export const range = (value, param) => {
  return value >= param[0] && value <= param[1]
}

/**
 * @example 验证一个值最小数,包括等于
 * @param {Number} value 须要验证的数值
 * @param {Number} param 最小数
 * @returns {Boolean} 是true, 否false
 */
export const min = (value, param) => {
  return value >= param
}

/**
 * @example 验证一个值最大数,包括等于
 * @param {Number} value 须要验证的数值
 * @param {Number} param 最大数
 * @returns {Boolean} 是true, 否false
 */
export const max = (value, param) => {
  return value <= param
}

/**
 * @example  验证一个字串长度范围[min, max]
 * @param {String} value 须要验证的数值
 * @param {Array} param [min最小长度, max最长度]
 * @returns {Boolean} 是true, 否false
 */
export const rangeLength = (value, param) => {
  return value.length >= param[0] && value.length <= param[1]
}

/**
 * @example  判断是否为空
 * @param {*} value 须要验证的数值
 * @returns {Boolean} 是空true, 否false
 */
export const empty = value => {
  switch (typeof value) {
    case 'undefined':
      return true
    case 'string':
      if (value.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length == 0) return true
      break
    case 'boolean':
      if (!value) return true
      break
    case 'number':
      if (value === 0 || isNaN(value)) return true
      break
    case 'object':
      if (value === null || value.length === 0) return true
      for (let { } in value) {
        return false
      }
      return true
  }
  return false
}

export default {
  email,
  mobile,
  url,
  date,
  dateISO,
  number,
  digits,
  idCard,
  carNo,
  amount,
  chinese,
  letter,
  enOrNum,
  contains,
  range,
  min,
  max,
  rangeLength,
  empty
}
